package com.common.base.widget

import android.content.Context
import android.content.res.TypedArray
import android.text.Editable
import android.text.Selection
import android.text.Spannable
import android.text.TextWatcher
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatEditText
import com.common.base.R
import java.util.regex.Matcher
import java.util.regex.Pattern
import java.util.regex.PatternSyntaxException


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：8/2/2023
 *
 * 描述：
 *
 * 修订历史：
 *
 */

/**
 * 作者：sosou
 *
 *
 * 版本：1.0
 *
 *
 * 创建日期：2022/3/301
 *
 *
 * 描述：emoji表情过滤器输入框
 *
 *
 * 修订历史：
 */
class ContainsEmojiEditText : AppCompatEditText {
    /**
     * 输入表情前的光标位置
     */
    private var cursorPos = 0

    /**
     * 输入表情前EditText中的文本
     */
    private var inputAfterText = ""

    /**
     * 是否重置了EditText的内容
     */
    private var resetText = false

    /**
     * 上下文对象
     */
    private var mContext: Context

    /**
     * [简要描述]:构造方法<br></br>
     * [详细描述]:构造方法<br></br>
     *
     * @param context 上下文对象
     * @author MaZhaoJun mWX326902
     */
    constructor(context: Context) : super(context) {
        mContext = context
        initEditText(context, null)
    }

    /**
     * [简要描述]:构造方法<br></br>
     * [详细描述]:构造方法<br></br>
     *
     * @param context 上下文对象
     * @param attrs   属性
     * @author MaZhaoJun mWX326902
     */
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        mContext = context
        initEditText(context, attrs)
    }

    /**
     * [简要描述]:构造方法<br></br>
     * [详细描述]:构造方法<br></br>
     *
     * @param context      上下文对象
     * @param attrs        属性
     * @param defStyleAttr 样式
     */
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        mContext = context
        initEditText(context, attrs)
    }

    /**
     * [简要描述]:初始化edittext 控件<br></br>
     * [详细描述]:初始化edittext 控件<br></br>
     */
    private fun initEditText(context: Context, attrs: AttributeSet?) {

        // 属性不能为空
        if (attrs == null) {
            throw RuntimeException(resources.getString(R.string.attr_not_null))
        }

        // 设置属性
        val typed: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView)
        setTypeface(typed.getInt(R.styleable.CustomTextView_cut_text_style, 0))

        // 回收属性表
        typed.recycle()
        includeFontPadding = false
        addTextChangedListener(object : TextWatcher {
            // 数量
            var cou = 0

            // 结束数
            var selectionEnd = 0

            // 设置允许输入的字符长度
            var mMaxLenth = 32

            /**
             * [简要描述]:文本改变之前<br></br>
             * [详细描述]:文本改变之前<br></br>
             *
             * @param s 序列
             * @param start 开始
             * @param before 已输入的值
             * @param count 数
             * @see TextWatcher.beforeTextChanged
             */
            override fun beforeTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                if (!resetText) {
                    cursorPos = getSelectionEnd()

                    // 这里用s.toString()而不直接用s是因为如果用s，
                    // 那么，inputAfterText和s在内存中指向的是同一个地址，s改变了，
                    // inputAfterText也就改变了，那么表情过滤就失败了
                    inputAfterText = s.toString()
                }
            }

            /**
             * [简要描述]:文本改变时<br></br>
             * [详细描述]:文本改变时<br></br>
             *
             * @param s 字符序列
             * @param start 开始
             * @param before 已输入的值
             * @param count 数
             * @see TextWatcher.onTextChanged
             */
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
                if (!resetText) {
                    if (before != 0) {
                        return
                    }
                    if (2 <= count) {
                        // 表情符号的字符长度最小为2
                        val input = s.subSequence(cursorPos, cursorPos + count)
                        if (containsEmoji(input.toString())) {
                            resetText = true
                            // Toast.makeText(mContext,
                            // "Does not support the input Emoji emoticons",
                            // Toast.LENGTH_SHORT).show();

                            // 是表情符号就将文本还原为输入表情符号之前的内容
                            setText(inputAfterText)
                            val text: CharSequence? = text
                            if (text is Spannable) {
                                Selection.setSelection(text, text.length)
                            }
                        }
                    }
                } else {
                    resetText = false
                }

                // CharSequence text = getText();
                // Spannable spanText = (Spannable) text;
                // Selection.setSelection(spanText, text.length());
                cou = before + count
                val editable = text.toString()

                // 过滤特殊字符
                val str = stringFilter(editable)
                if (editable != str) {
                    setText(str)
                }

                // // 设置光标末位
                // setSelection(length());
                cou = length()
            }

            /**
             * [简要描述]:文本改变之后<br></br>
             * [详细描述]:文本改变之后<br></br>
             *
             * @param editable 输入框
             * @see TextWatcher.afterTextChanged
             */
            override fun afterTextChanged(editable: Editable) {

//                if (mMaxLenth < cou)
//                {
//                    selectionEnd = getSelectionEnd();
//                    editable.delete(mMaxLenth, selectionEnd);
//                }
            }
        })
    }
    //    /**
    //     * [简要描述]:默认字体<br/>
    //     * [详细描述]:默认字体类型<br/>
    //     *
    //     * @param tf    字体
    //     * @param style 风格
    //     * @see android.widget.TextView#setTypeface(Typeface,
    //     * int)
    //     */
    //    @Override
    //    public void setTypeface(Typeface tf, int style) {
    ////        super.setTypeface(Typeface.createFromAsset(getContext().getAssets(), FConfig.MED));
    //    }
    /**
     * 设置文字字体（判断文字位置。设置文字字体）
     *
     * @param textStyle 文字
     */
    fun setTypeface(textStyle: Int) {
//        when (textStyle) {
//            1 -> setTypeface(App.typefaceBold)
//            2 -> setTypeface(App.typefaceMedium)
//            else -> setTypeface(App.typefaceRegular)
//        }
    }

    companion object {
        /**
         * [简要描述]:检测是否有emoji表情<br></br>
         * [详细描述]:检测是否有emoji表情<br></br>
         *
         * @param source 目标
         * @return 状态
         */
        fun containsEmoji(source: String): Boolean {
            val len = source.length
            for (i in 0 until len) {
                val codePoint = source[i]
                if (!isEmojiCharacter(codePoint)) { // 如果不能匹配,则该字符是Emoji表情
                    return true
                }
            }
            return false
        }

        /**
         * [简要描述]:判断是否是Emoji<br></br>
         * [详细描述]:判断是否是Emoji<br></br>
         *
         * @param codePoint 比较的单个字符
         * @return 字符
         */
        private fun isEmojiCharacter(codePoint: Char): Boolean {
            return (codePoint.code == 0x0 || codePoint.code == 0x9 || codePoint.code == 0xA || codePoint.code == 0xD || codePoint.code >= 0x20 && codePoint.code <= 0xD7FF || codePoint.code >= 0xE000 && codePoint.code <= 0xFFFD || codePoint.code >= 0x10000 && (codePoint <= 0x10FFFF.toChar()))
        }

        /**
         * [简要描述]:过滤emoji表情字符<br></br>
         * [详细描述]:过滤emoji表情字符<br></br>
         *
         * @param str 字符
         * @return 值
         * @throws PatternSyntaxException
         */
        @Throws(PatternSyntaxException::class)
        fun stringFilter(str: String?): String {
            val regEx = "[/\\:*?<>|\"\n\t]"
            val p: Pattern = Pattern.compile(
                "[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
                Pattern.UNICODE_CASE or Pattern.CASE_INSENSITIVE
            )
            val m: Matcher = p.matcher(str)
            return m.replaceAll("")
        }
    }
}